#include <stdio.h>

struct A
{
    virtual void vfa() { printf("Calling %s\n", "A::vfa"); }

};

struct B
{
    virtual void vfb() { printf("Calling %s, this:%p\n", "B::vfb", this); }
    int mfb(int n) { return printf("Calling %s, this:%p, n:%d\n", "B::mfb", this, n); }

};

struct C : A, B
{
    virtual void vfa() { printf("Calling %s, this:%p\n", "C::vfa", this); }
    virtual void vfb() { printf("Calling %s, this:%p\n", "C::vfb", this); }
};

struct D
{
    virtual void vfd() { printf("Calling %s, this:%p\n", "D::vfd", this); }

};

struct E : D, C
{
    virtual void vfa() { printf("Calling %s, this:%p\n", "E::vfa", this); }
    virtual void vfb() { printf("Calling %s, this:%p\n", "E::vfb", this); }
    virtual void vfd() { printf("Calling %s, this:%p\n", "E::vfd", this); }

};

//ed|ca|b

int main(void)
{
    E e;
    auto& a = dynamic_cast<A&>(e);
    auto& b = dynamic_cast<B&>(e);
    auto& c = dynamic_cast<C&>(e);
    auto& d = dynamic_cast<D&>(e);
    printf("a:%p, b:%p, c:%p, d:%p, e:%p\n", &a, &b, &c, &d, &e);
    e.vfa();
    e.vfb();
    e.mfb(0);
    e.vfd();
    a.vfa();
    b.vfb();
    c.vfa();
    c.vfb();
    return 0;
}
